/**
 * 与某个角色关联的菜单树面板，提供添加和删除关联功能
 * @author linzongxue
 * @create_date 2012-1-7
 */
define(function(){
	var RoleMenuPanel = Ext.extend(Ext.tree.TreePanel, {
		roleId: null,
		title: '关联菜单',
        autoScroll: true,
		initComponent: function(){
			Ext.apply(this, {
				tbar: au.permit([
	            	{text: '保存', permitId:'sys.role.updateMenu', handler: this.save, scope: this, iconCls: 'icon-add', tooltip:'保存角色与菜单的关联'},
					'-',
					{text: '刷新', handler: function(){this.refresh(true);}, scope: this, iconCls: 'icon-refresh'},
					'-',
					{handler: this.expandAll, scope: this, iconCls: 'icon-expand-all', tooltip:'全部展开'},
					{handler: this.collapseAll, scope: this, iconCls: 'icon-collapse-all', tooltip:'全部收缩'},
					'->',
				    {xtype: 'label', name:'curRole'} //显示角色名称
	            ]),
	            dataUrl: 'sys/menu/getAllMenusTreeData.do',
		        root: {
		        	listeners:{
			        	expand: function(node){ //展开全部节点
			        		node.expand(true);
		        		}
		        	}
		        },
		        rootVisible: false
			});
			RoleMenuPanel.superclass.initComponent.call(this);
			this.on({
				activate: function(){
					this.refresh();
				},
				click: function(node, e){
	        		node.getUI().toggleCheck();
	        		return node.getUI().isChecked();
	        	},
	            checkchange: this.onCheckChange
			});
		},
		role: null, //当前角色信息
		roleChanged: false,
		lastMenuIds: null, //保存之前关联的菜单id
		treeExpandedAll: false, //树节点是否已全部展开
		/**
		 * 保存
		 */
		save: function(){
			if (!this.role){
				cu.hint('请选择一个角色');
				return;
			}
			//分别找出要添加的菜单和要删除的菜单
			var newMenuIds = this.getChecked('id');
			var addMenuIds = [], removeMenuIds = this.lastMenuIds;
			this.lastMenuIds = newMenuIds;
			Ext.each(newMenuIds, function(newId){
				var isNew = true;
				Ext.each(removeMenuIds, function(lastId){
					if (newId === lastId){
						removeMenuIds.remove(lastId);
						isNew = false;
						return false;
					}
				}, this);
				isNew && addMenuIds.push(newId);
			}, this);
			//检查是否有修改
			if (Ext.isEmpty(addMenuIds) && Ext.isEmpty(removeMenuIds)){
				cu.hint('没有要保存的数据');
				return;
			}
			//提交修改
			cu.post({
				url: 'sys/role/saveMenusOfRole.do',
				params: {roleId: this.role.id, addMenuIds: addMenuIds, removeMenuIds: removeMenuIds},
				success: function(){
					cu.hint('保存成功');
				},
				scope: this
			});
		},
		/**
		 * 刷新关联数据
		 * @param force 是否强制刷新，true强制刷新，false当角色改变时刷新
		 */
		refresh: function(force){
			var curRoleLabel =  this.getTopToolbar().find('name', 'curRole')[0];
			if (!this.role){
				if (force) cu.hint('没有选择角色');
				curRoleLabel.setText('未选中角色');
				//去除所有打勾
				this.lastMenuIds = null;
				this.root.eachChild(function(node){node.getUI().toggleCheck(false)});
				return;
			}
			curRoleLabel.setText('当前角色：' + this.role.name);
			this.loadMenusOfRole(force);
			this.roleChanged = false;
		},
		setRole: function(role){
			this.role = role;
			this.roleChanged = true;
		},
		/**
		 * 加载关联的菜单数据并打勾
		 * @param force 是否强制刷新，true强制刷新，false当角色改变时刷新
		 */
		loadMenusOfRole: function(force){
			if (!force && !this.roleChanged) return;
			this.lastMenuIds = [];
			if (force){ //刷新所有菜单
				this.treeExpandedAll = false;
				this.loader.load(this.root, function(node){node.expand(true);});
			}
			//获取新数据并勾选
			cu.get({
				url:'sys/role/getMenusOfRole.do',
				params: {roleId: this.role.id},
				success: function(data){
					this.doWhenTreeExpandedAll(function(){
						Ext.each(data, function(menu){
							var node = this.getNodeById(menu.id);
							if(node) this.checkNodeWithoutEvent(node, true); //别用node.toggleCheck方法
							this.lastMenuIds.push(menu.id);
						}, this);
					}, this);
				},
				waitMsg: null,
				scope: this
			});
		},
		/**
		 * 当树节点全部展开时执行方法
		 */
		doWhenTreeExpandedAll: function(fn, scope){
			if (this.treeExpandedAll){
				fn.call(scope);
			}
			else{
				new Ext.util.TaskRunner().start({
					run: function(){
						var expandedAll = true;
						this.root.cascade(function(node){
							if (!node.isExpanded()){
								expandedAll = false;
								return false;
							}
						});
						if (expandedAll){
							fn.call(scope);
							this.treeExpandedAll = true;
							return false; //结束定时调度
						}
					},
					interval: 50,
					scope: this
				});
			}
		},
		/**
		 * 菜单树节点的勾选事件
		 */
		onCheckChange: function(node, checked){
        	if (checked){
        		//确保父节点被勾选，但不触发checkchange事件
        		if (!node.parentNode.getUI().isChecked()){
        			var p = node.parentNode;
        			while( p != node.ownerTree.root){
        				this.checkNodeWithoutEvent(p, true);
        				p = p.parentNode;
        			}
        		}
        		//勾选所有子节点
        		node.eachChild(function(child){
        			child.getUI().toggleCheck(true);
        		});
        		node.getUI().addClass('tree-node-checked');
        	}
        	else{
        		//取消选中所有子节点
        		node.eachChild(function(child){
        			child.getUI().toggleCheck(false);
        		});
        		node.getUI().removeClass('tree-node-checked');
        	}
        },
        /**
         * 在节点中打勾，不触发checkchange事件
         */
        checkNodeWithoutEvent: function(node, checked){
    		node.getUI().checkbox.checked = checked;
    		node.getUI().checkbox.defaultChecked = checked;
            node.attributes.checked = checked;
            checked ? node.getUI().addClass('tree-node-checked') : node.getUI().removeClass('tree-node-checked');
        }
	});
	return RoleMenuPanel;
});